package com.example.system.service.sysuser.Impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.common.core.constants.HttpConstants;
import com.example.common.core.domin.LoginUser;
import com.example.common.core.domin.R;
import com.example.common.core.domin.vo.LoginUserVO;
import com.example.common.core.enums.ResultCode;
import com.example.common.core.enums.UserIdentity;
import com.example.common.security.exception.ServiceException;
import com.example.common.security.service.TokenService;
import com.example.system.Utils.BCryptUtils;
import com.example.system.domin.sysUser.SysUser;
import com.example.system.domin.sysUser.dto.SysUserSaveDTO;
import com.example.system.mapper.sysuser.SysUserMapper;
import com.example.system.service.sysuser.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
@RefreshScope  //这个注解就是后续nacos中的配置文件发生了变更,不需要重启服务也可以生效
public class SysUserServiceImpl implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private TokenService tokenService;

    @Value("${jwt.secret}")
    private String secret;

    @Override
    //维护性,性能,安全
    public R<String> login(String userAccount, String password) {
        //1.通过账号去数据库中查询对应的用户信息
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        SysUser user = sysUserMapper.selectOne(wrapper.select(SysUser::getPassword,SysUser::getUserId,SysUser::getNickName).eq(SysUser::getUserAccount, userAccount));
        //2.先判断是否存在登录用户
        if(user == null){
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        if(BCryptUtils.matchesPassword(password, user.getPassword())){

            return R.ok(tokenService.createToken(user.getUserId(),
                    secret,UserIdentity.ADMIN.getValue(),user.getNickName(),null));
        }
        return R.fail(ResultCode.FAILED_LOGIN);
    }

    @Override
    public boolean logout(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        return tokenService.deleteLoginUser(token,secret);
    }

    @Override
    public R<LoginUserVO> info(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }

        LoginUser loginUser = tokenService.getLoginUser(token,secret);
        if(loginUser == null){
            return R.fail();
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        loginUserVO.setNickName(loginUser.getNickName());
        return R.ok(loginUserVO);
    }

    @Override
    public int add(SysUserSaveDTO sysUserSaveDTO) {
        //在添加之前,我们应该做一个参数的校验(用户名是否重复)
        List<SysUser> selectList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserAccount,sysUserSaveDTO.getUserAccount()));
        if(CollectionUtil.isNotEmpty(selectList)) {
            //这块就抛出一个自定义的异常
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }
        //将DTO 转换为 实体
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        //密码是加密之后进行存储的
        sysUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));
        return sysUserMapper.insert(sysUser);
    }


}
